/*************************************************
Author: will
Date: 10/16/2012
Description:
Notes:
*************************************************/

#ifndef __CUserStorage_h__
#define __CUserStorage_h__

#include "CTArray.h"
#include "CStorage.h"
#include "commclass.h"
#include "commerrno.h"

class CStorageMgr;
class CCmdDropItem;
class CUserStorage
{
public:
    friend class CStorageMgr;
    friend class CCmdDropItem;

	CUserStorage()
    {
        _uiGID = 0;
		_shMaxBagGridCount = SYS_DEFAULT_GRID_NUM_BAG;
		_shMaxWareHouseGridCount = SYS_DEFAULT_GRID_NUM_WAREHOUSE;
		_usBagEmptyGridBegin = 0;
		_usWareHouseEmptyGridBegin = 0;
	    _astBagGrids.m_iUsedCount = MAX_BAG_GRID_COUNT;
	    _astWareHouseGrids.m_iUsedCount = MAX_WAREHOUSE_GRID_COUNT;

	    for (int i = 0; i < _astBagGrids.Size(); ++i)
	    {
	        _astBagGrids[i] = -1;
	    }

	    for (int i = 0; i < _astWareHouseGrids.Size(); ++i)
	    {
	        _astWareHouseGrids[i] = -1;
	    }
	}

	virtual ~CUserStorage()
    {
	}

    void Clear();

    static size_t CountSize();
    int Init(const char* sBuff);
    int AddGridData(CStorageGrid& stGrid);

    bool BagIsFull() const;
    bool WareHouseIsFull() const;
    bool BagIsEmpty();
    bool WareHouseIsEmpty();

    void SetMaxBagGridCount(short shMaxCount);
    void SetMaxWareHouseGridCount(short shMaxCount);
    int GetMaxBagGridCount();
    int GetMaxWareHouseGridCount();
    int GetFreeGridCount(bool bOnlyBag);
	short GetWareHouseUnlockGridCount() const
	{
		return _shMaxWareHouseGridCount - SYS_DEFAULT_GRID_NUM_WAREHOUSE;
	}
	short GetBagUnlockGridCount() const
	{
		return _shMaxBagGridCount - SYS_DEFAULT_GRID_NUM_BAG;
	}

    int GetBagHeadIndex() const;
    int GetWareHouseHeadIndex() const;
    int GetBagNextIndex(unsigned short usPos);
    int GetWareHouseNextIndex(unsigned short usPos);
	int GetGridInfoByIndex(int iIndex, CStorageGrid& stGrid);
	int GetGridByGroupKey(CStorageItemGroupKey& stGoupKey, CStorageGrid& stGrid);
    int GetGridInfoByKey(CStorageKey& stKey, CStorageGrid& stGrid);
    int GetGridInfoByPos(bool bIsInBag, unsigned short usPos, CStorageGrid& stGrid);

    //此函数不做叠加操作，如果需要叠加需要调用AddItem函数
    //如果在stGrid中指定了存放位置,而背包(仓库)中指定位置已保存了其他物品时,加入失败
	int AddGrid(CStorageGrid& stGrid);
    int AddToBag(CStorageGrid& stGrid);
    int AddToWareHouse(CStorageGrid& stGrid);

    int TakeOutGrid(bool bIsInBag, unsigned short usPos, CStorageGrid& stGrid);
	int ReplaceGrid(bool bIsInBag, unsigned short usPos, CStorageGrid& stNewGrid);

    int GetItemCount(unsigned char ucItemType, unsigned int _uiItemID, bool bOnlyCheckBag = false);

    //叠加到背包和仓库中, 要么全加入或者全不加入.
    int AddAllItem(unsigned char ucItemType, unsigned int uiItemID, short  & shCount, bool bOnlyFillBag = true);

    bool IsAddible(unsigned char ucItemType, unsigned int uiItemID, short shCount, bool bOnlyFillBag = true);

    int TakeOutItem(unsigned char ucItemType, unsigned int uiItemID, short shCount, short &shLeftCount);
    int TakeOutItem(unsigned char ucItemType, unsigned int uiItemID, short shCount);
    int TakeOutItemOnGird(bool bIsInBag, unsigned short usPos, short shCount);

	int UnLockBagGrid();
	int UnLockWareGrid();

    //是否有可用的等级礼包
    bool IsLevelGiftAvail(short shRoleLevel);

    //排序
    int SortStorage(bool bIsSortBag);

	int SwapStorageItemPos(int iStorageType1, int iItemPos1,CStorageGrid & stGrid1,
 						   int iStorageType2, int iItemPos2,CStorageGrid & stGrid2);
    int SwapToEmptyGrid(unsigned char ucStorageType1, int iItemPos1,CStorageGrid & stGrid1,
                        unsigned char ucStorageType2, int iItemPos2,CStorageGrid & stGrid2);

	int MoveGrid(CStorageGrid & stGrid, bool bNewInBag, int iNewPos);
	int SwapGrid(CStorageGrid & stGrid1, CStorageGrid & stGrid2);

    //合并入仓库
    int MergeToWareHouse();
    int TakeOutItem(bool bIsFromBag, unsigned char ucItemType, unsigned int uiItemID, short shCount, short& shLeftCount);

	int CheckScrollMaterial(unsigned short usScroll);
    int GetScrollGoldCost(unsigned short usScrollConfigId, int &iGoldCost);

    //背包中使用卷轴
    int MakeItem(CStorageGrid & stScrollGrid, unsigned char ucOpType, bool bScrollNecessary);

    //魔晶合成
    int CombineCrystal (unsigned char ucOldCrystalId, unsigned char ucCombinedId);

    //获取某类物品可添加的最大个数
    int GetFreeCount(unsigned char ucItemType, unsigned short usConfigId);

    //一键合成
    int OneKeyCrystal (CPlayerDetailInfo & stPlayerDetailInfo, unsigned char ucCombinedLevel);

    //清空背包+仓库
    void SetEmpty();

    //获取背包空格数
    int GetBagEmptyGridCount();

    int ClearTime(unsigned short usBagPos, int iNewTime);
public:
    unsigned int _uiGID;
    short          _shMaxBagGridCount;		   //用户可使用的背包格子数(=系统缺省打开的+用户手工解锁的)
    short          _shMaxWareHouseGridCount;   //用户可使用的仓库格子数(=系统缺省打开的+用户手工解锁的)

private:
    //增加物品时作叠加操作, 尽可能叠加, shCount保存未放下的物品数目
    int AddItem(unsigned char ucItemType, unsigned int uiItemID, short& shCount, bool bOnlyFillBag = true);

    unsigned short _usBagEmptyGridBegin;       //可操作的取值范围[0, _shMaxBagGridCount)
    unsigned short _usWareHouseEmptyGridBegin; //可操作的取值范围[0, _usWareHouseEmptyGridBegin)
    CTLib::CTArray<int, MAX_BAG_GRID_COUNT> _astBagGrids;
    CTLib::CTArray<int, MAX_WAREHOUSE_GRID_COUNT> _astWareHouseGrids;
    CStorageHash _stStorageHash;

    unsigned short FindNextEmptyGridInBag(unsigned short usPos);
    unsigned short FindNextEmptyGridInWareHouse(unsigned short usPos);

    typedef CTArray<unsigned short, MAX_CRYSTAL_ATTR_TYPE * MAX_CRYSTAL_LEVLE> T_ORDERED_CONFIG_ID;

    int AddToOrderedSeq(CStorageGrid & stCrystal, T_ORDERED_CONFIG_ID & astOrderedSeq);
    int GetOrderedSeq(T_ORDERED_CONFIG_ID & astOrderedSeq);
    int  SortOneItem(unsigned char ucItemType, unsigned short uiItemID, short &shCnt);

    bool IsPosValid (bool bIsInBag, unsigned short usPos);
};

#endif // __CUserStorage_h__

